package com.brainshare.system.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import com.brainshare.an.domain.AnMechanism;
import com.brainshare.an.domain.AnWechatUser;
import com.brainshare.an.service.IAnMechanismService;
import com.brainshare.common.constant.Constants;
import com.brainshare.common.enums.BuriedPointPathEnum;
import com.brainshare.common.enums.YNEnum;
import com.brainshare.common.utils.AesUtils;
import com.brainshare.common.utils.DateUtils;
import com.brainshare.common.utils.MessageUtils;
import com.brainshare.common.utils.ip.IpUtils;
import com.brainshare.system.domain.BuriedPointPath;
import com.brainshare.system.domain.param.BuriedPointParam;
import com.brainshare.system.domain.query.BuriedPointQuery;
import com.brainshare.system.domain.vo.SysBuriedPointVO;
import com.brainshare.system.manager.AsyncFactory;
import com.brainshare.system.manager.AsyncManager;
import com.brainshare.utils.CommonUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.brainshare.system.mapper.SysBuriedPointMapper;
import com.brainshare.system.domain.SysBuriedPoint;
import com.brainshare.system.service.ISysBuriedPointService;

import javax.servlet.http.HttpServletRequest;

/**
 * 埋点记录Service业务层处理
 * 
 * @author ruoyi
 * @date 2023-08-22
 */
@Service
public class SysBuriedPointServiceImpl implements ISysBuriedPointService
{

    /**
     * 日志
     */
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private SysBuriedPointMapper sysBuriedPointMapper;

    @Autowired
    private IAnMechanismService anMechanismService;

    /**
     * 查询埋点记录
     * 
     * @param id 埋点记录主键
     * @return 埋点记录
     */
    @Override
    public SysBuriedPoint selectSysBuriedPointById(Long id)
    {
        return sysBuriedPointMapper.selectSysBuriedPointById(id);
    }

    @Override
    public List<SysBuriedPoint> getBuriedPointList(BuriedPointQuery buriedPointQuery) {
        BuriedPointQuery.checkParam(buriedPointQuery);
        BuriedPointQuery.handleParam(buriedPointQuery);
        return sysBuriedPointMapper.getSysBuriedPointList(buriedPointQuery);
    }

    public List<SysBuriedPointVO> getSysBuriedPointVO(List<SysBuriedPoint> sysBuriedPointList) {
        if (CollectionUtils.isEmpty(sysBuriedPointList)) {
            return null;
        }
        List<BuriedPointPath> buriedPointList = BuriedPointPath.getBuriedPointList();
        List<SysBuriedPointVO> list = new ArrayList<>();
        SysBuriedPointVO sysBuriedPointVO = null;
        for (SysBuriedPoint sysBuriedPoint : sysBuriedPointList) {
            sysBuriedPointVO = new SysBuriedPointVO();
            BeanUtils.copyProperties(sysBuriedPoint, sysBuriedPointVO);
            sysBuriedPointVO.setStrCreateTime(DateUtils.getFormatDate(sysBuriedPointVO.getCreateTime(), DateUtils.YYYY_MM_DD_HH_MM_SS));
            BuriedPointPath sysBuriedPath = getSysBuriedPoint(buriedPointList, sysBuriedPoint.getSection(), sysBuriedPoint.getModule(), sysBuriedPoint.getFunction());
            if (null == sysBuriedPath) {
                logger.warn("未查询到埋点路径，入参section{} module{} function{}", sysBuriedPoint.getSection(), sysBuriedPoint.getModule(), sysBuriedPoint.getFunction());
            } else {
                sysBuriedPointVO.setSectionName(sysBuriedPath.getSectionName());
                sysBuriedPointVO.setModuleName(sysBuriedPath.getModuleName());
                sysBuriedPointVO.setFunctionName(sysBuriedPath.getFunctionName());
            }
            list.add(sysBuriedPointVO);
        }
        return list;
    }

    private BuriedPointPath getSysBuriedPoint(List<BuriedPointPath> sysBuriedPointList, String section, String module, String function) {
        if (CollectionUtils.isEmpty(sysBuriedPointList)
                || StringUtils.isBlank(section)
                || StringUtils.isBlank(module)
                || StringUtils.isBlank(function)
        ) {
            logger.warn("未查询到埋点路径，入参section{} module{} function{}", section, module, function);
            return null;
        }
        Optional<BuriedPointPath> optionalBuriedPointPath = sysBuriedPointList.stream()
                .filter(item -> item.getSection().equals(section))
                .filter(item -> item.getModule().equals(module))
                .filter(item -> item.getFunction().equals(function))
                .findFirst();
        BuriedPointPath buriedPointPath = optionalBuriedPointPath.orElse(null);
        return buriedPointPath;
    }

    /**
     * 查询埋点记录列表
     * 
     * @param sysBuriedPoint 埋点记录
     * @return 埋点记录
     */
    @Override
    public List<SysBuriedPoint> selectSysBuriedPointList(SysBuriedPoint sysBuriedPoint)
    {
        return sysBuriedPointMapper.selectSysBuriedPointList(sysBuriedPoint);
    }

    /**
     * 新增埋点记录
     * 
     * @param sysBuriedPoint 埋点记录
     * @return 结果
     */
    @Override
    public int insertSysBuriedPoint(SysBuriedPoint sysBuriedPoint)
    {
        sysBuriedPoint.setCreateTime(DateUtils.getNowDate());
        return sysBuriedPointMapper.insertSysBuriedPoint(sysBuriedPoint);
    }

    @Override
    public Integer addBuriedPoint(HttpServletRequest request, BuriedPointParam buriedPointParam) {
        long ts = DateUtils.getTimeMillis();
        try {
            logger.info("ts:{}，新增埋点记录，入参：{}", ts, buriedPointParam);
            SysBuriedPoint sysBuriedPoint = constructSysBuriedPoint(request, buriedPointParam);
            boolean booleanAnEntranceFlag = isAnEntrance(buriedPointParam);
            int insertResult = sysBuriedPointMapper.insertSysBuriedPoint(sysBuriedPoint);
            logger.info("ts:{}，新增埋点记录，结果{}", ts, insertResult);
            if (booleanAnEntranceFlag) {
                SysBuriedPoint sysBuriedPointParam = new SysBuriedPoint();
                sysBuriedPointParam.setCustomerId(sysBuriedPoint.getCustomerId());
                sysBuriedPointParam.setAnEntranceFlag(YNEnum.YES.getCode());
                List<SysBuriedPoint> sysBuriedPointList = sysBuriedPointMapper.selectSysBuriedPointList(sysBuriedPointParam);
                if (CollectionUtils.isNotEmpty(sysBuriedPointList)) {
                    Date date = DateUtils.getNowDate();
                    Long customerId = sysBuriedPoint.getCustomerId();
                    String updateUser = null == customerId ? null : String.valueOf(customerId);
                    sysBuriedPointParam.setAnEntranceFlag(YNEnum.NO.getCode());
                    sysBuriedPointParam.setUpdateUser(updateUser);
                    sysBuriedPointParam.setUpdateTime(date);
                    List<Long> idList = sysBuriedPointList.stream().map(item -> item.getId()).collect(Collectors.toList());
                    idList.remove(sysBuriedPoint.getId());
                    if (CollectionUtils.isNotEmpty(idList)) {
                        sysBuriedPointParam.setIdList(idList);
                        int updateResult = sysBuriedPointMapper.updateBuriedPoint(sysBuriedPointParam);
                        logger.info("ts:{}，更新埋点记录，结果{}", ts, updateResult);
                        return insertResult + updateResult;
                    }
                }
            }
            return insertResult;
        } catch (Exception e) {
            // AsyncManager.me().execute(AsyncFactory.recordLogininfor("admin", Constants.LOGIN_FAIL,
            //         MessageUtils.message("user.password.retry.limit.exceed", 1, 1)));
            logger.error("新增埋点记录异常", e);
            return null;
        }
    }

    private SysBuriedPoint constructSysBuriedPoint(HttpServletRequest request, BuriedPointParam buriedPointParam) {
        SysBuriedPoint sysBuriedPoint = new SysBuriedPoint();
        if (StringUtils.isNotBlank(buriedPointParam.getOrgNo())) {
            String orgNo = AesUtils.decryptHex(buriedPointParam.getOrgNo());
            buriedPointParam.setOrgNo(orgNo);
        }
        BeanUtils.copyProperties(buriedPointParam, sysBuriedPoint);
        AnWechatUser user = null;
        try {
            user = CommonUtils.getAnWechatUser(request);
        } catch (Exception e) {
            logger.error("获取会员信息异常", e);
        }
        String ip = IpUtils.getIpAddr(request);
        sysBuriedPoint.setIp(ip);

        Long customerId = null == user ? null : user.getWechatUserId();
        String phone = null == user ? null : user.getPhone();
        String customerName = null == user ? null : user.getNickName();
        Long mechanismId = null == user ? null : user.getMechanismId();
        String orgNo = buriedPointParam.getOrgNo();
        if (StringUtils.isBlank(orgNo) && null != mechanismId) {
            orgNo = String.valueOf(mechanismId);
        }
        AnMechanism mechanism = null;
        if (StringUtils.isNotBlank(orgNo)) {
            mechanism = anMechanismService.selectAnMechanismByMechanismId(Long.valueOf(orgNo));
        }
        String orgName = null != mechanism ? mechanism.getMechanismName() : null;
        Date nowDate = DateUtils.getNowDate();
        String strDate = DateUtils.getFormatDate(nowDate, DateUtils.YYYY_MM_DD);

        boolean boolAnEntranceFlag = isAnEntrance(buriedPointParam);
        Integer anEntranceFlag = boolAnEntranceFlag?YNEnum.YES.getCode():YNEnum.NO.getCode();
        sysBuriedPoint.setAnEntranceFlag(anEntranceFlag);

        sysBuriedPoint.setCustomerId(customerId);
        sysBuriedPoint.setPhone(phone);
        sysBuriedPoint.setCustomerName(customerName);
        sysBuriedPoint.setOrgNo(orgNo);
        sysBuriedPoint.setOrgName(orgName);
        sysBuriedPoint.setCreateDate(strDate);
        sysBuriedPoint.setYn(YNEnum.NO.getCode());
        String createUser = null == customerId ? null : String.valueOf(customerId);
        sysBuriedPoint.setCreateUser(createUser);
        sysBuriedPoint.setCreateTime(nowDate);

        return sysBuriedPoint;
    }

    private boolean isAnEntrance(BuriedPointParam buriedPointParam)
    {
        if (String.valueOf(BuriedPointPathEnum.ME_AN_ENTRANCE.getSectionCode()).equals(buriedPointParam.getSection()) &&
         String.valueOf(BuriedPointPathEnum.ME_AN_ENTRANCE.getModuleCode()).equals(buriedPointParam.getModule()) &&
         String.valueOf(BuriedPointPathEnum.ME_AN_ENTRANCE.getFunctionCode()).equals(buriedPointParam.getFunction())){
            return true;
        }

        if (String.valueOf(BuriedPointPathEnum.INDEX_INDEX_AN.getSectionCode()).equals(buriedPointParam.getSection()) &&
                String.valueOf(BuriedPointPathEnum.INDEX_INDEX_AN.getModuleCode()).equals(buriedPointParam.getModule()) &&
                String.valueOf(BuriedPointPathEnum.INDEX_INDEX_AN.getFunctionCode()).equals(buriedPointParam.getFunction())){
            return true;
        }

        if (String.valueOf(BuriedPointPathEnum.INDEX_BANNER_RULE_AN.getSectionCode()).equals(buriedPointParam.getSection()) &&
                String.valueOf(BuriedPointPathEnum.INDEX_BANNER_RULE_AN.getModuleCode()).equals(buriedPointParam.getModule()) &&
                String.valueOf(BuriedPointPathEnum.INDEX_BANNER_RULE_AN.getFunctionCode()).equals(buriedPointParam.getFunction())){
            return true;
        }

        return false;
    }


    /**
     * 修改埋点记录
     * 
     * @param sysBuriedPoint 埋点记录
     * @return 结果
     */
    @Override
    public int updateSysBuriedPoint(SysBuriedPoint sysBuriedPoint)
    {
        sysBuriedPoint.setUpdateTime(DateUtils.getNowDate());
        return sysBuriedPointMapper.updateSysBuriedPoint(sysBuriedPoint);
    }

    /**
     * 批量删除埋点记录
     * 
     * @param ids 需要删除的埋点记录主键
     * @return 结果
     */
    @Override
    public int deleteSysBuriedPointByIds(Long[] ids)
    {
        return sysBuriedPointMapper.deleteSysBuriedPointByIds(ids);
    }

    /**
     * 删除埋点记录信息
     * 
     * @param id 埋点记录主键
     * @return 结果
     */
    @Override
    public int deleteSysBuriedPointById(Long id)
    {
        return sysBuriedPointMapper.deleteSysBuriedPointById(id);
    }
}
